package main

import "fmt"

/**
func A() {
	defer B()
	//code to do something
}

func A() {
	r = deferproc(8, B)
	if r > 0 { // 和panic recover 有关，暂时忽略
		goto ret
	}

	//code to do  something

	runtime.deferreturn()
	return
ret:
	runtime.deferreturn
}
**/

func main() {
	//basic()
	//DemoA()
	//DemoB()
	//DemoC()
	DemoE()
}

func basic() {
	a := 1
	// defer 函数在此处注册,生成一个defer结构体，添加到defer链表头，main中defer后面的函数执行完了才会执行defer
	// 注册的时候，被注册函数的参数必须确定。(即此处注册A函数时，会直接将B函数的结果作为入参)，B函数入参值为1，返回2
	defer A(B(a)) // B的结果是2，最终注册的A函数中会打印3
	a++
	fmt.Println(a)
}

func B(a int) int {
	a++
	return a
}

func A(a int) {
	a++
	fmt.Println("defer:", a)
}

func DemoA() {
	a, b := 1, 2
	defer func(b int) {
		fmt.Println("defer:", a, b) //2,2
	}(b)
	a++
	fmt.Println(a, b) //2,2
}

func A1(a int) {
	fmt.Println("defer:", a) //1
}
func DemoB() {
	a, b := 1, 2
	defer A1(a)
	a = a + b
	fmt.Println(a, b) //3,2
}

func DemoC() {
	a, b := 1, 2
	defer func(b int) {
		fmt.Println("defer:", a, b) //2,2
	}(b)
	a++
	b++
	fmt.Println(a, b) //2,3
}

func incr(a int) int {
	var b int

	defer func() {
		a++
		b++
	}()
	a++
	b = a
	return b
}
func DemoE() {
	var a, b int
	b = incr(a)
	println(a, b) //0,1
}
